// nb_timer.c

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_timer.h"

#include "newbit/nb_timer.h"
#include "newbit/nb_hal.h"


#define OUT_FREQ 1000000



//#define BSP_CLK_HFXO_INIT                      CMU_HFXOINIT_DEFAULT
//#define BSP_CLK_HFXO_FREQ                     (38400000UL)




// timer clock enable
static void nb_clock_init(void)
{
	CMU_ClockSelectSet(CMU_CLOCK_TIMER_USED ,  cmuSelect_HFXO );

	CMU_ClockEnable(CMU_CLOCK_TIMER_USED, true);
}

// timer configuration
void nb_timer_init(void)
{
  
 uint32_t timerFreq = 0;
  // Initialize the timer 
  TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
  // Configure TIMER_USED Compare/Capture for output compare
  TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;

  timerInit.prescale = timerPrescale1;
  timerInit.enable = false;
  timerCCInit.mode = timerCCModeCompare;
  timerCCInit.cmoa = timerOutputActionToggle;

  // configure, but do not start timer
  TIMER_Init(TIMER_USED, &timerInit);

  // Route Timer0 CC0 output to PC3
  GPIO->TIMERROUTE[TIMER_INDEX_0].ROUTEEN  = GPIO_TIMER_ROUTEEN_CC0PEN;

  GPIO->TIMERROUTE[TIMER_INDEX_0].CC0ROUTE = (TIMER_USED_GPIO_PORT_0 << _GPIO_TIMER_CC0ROUTE_PORT_SHIFT)
  								  | (TIMER_USED_GPIO_PIN_0 << _GPIO_TIMER_CC0ROUTE_PIN_SHIFT);

  TIMER_InitCC(TIMER_USED, 0, &timerCCInit);

  // Set Top value
  // Note each overflow event constitutes 1/2 the signal period
  timerFreq = CMU_ClockFreqGet(CMU_CLOCK_TIMER_USED)/(timerInit.prescale + 1);
  int topValue =  timerFreq / (2*OUT_FREQ) - 1;
  TIMER_TopSet (TIMER_USED, topValue);

  /* Start the timer */
  TIMER_Enable(TIMER_USED, true);
}

// set timer TOP value
void nb_timer_top_value(int val)
{
	TIMER_Enable(TIMER_USED, false);

	TIMER_TopSet (TIMER_USED, val);

	TIMER_Enable(TIMER_USED, true);
}


// timer inital & start , the main of those code
// normally, call in emberAfMainInitCallback();
void nb_start_running(void)
{
	nb_gpio_init();
	nb_clock_init();
	nb_timer_init();
}


// test function, no input para
// set a event, eg. BUTTON, UART to call this funcation
void test_nb_timer_top_change(void)
{
	static int tops[6] = {0, 1, 10, 100, 1000,  0xFFFF };

	static int index = 0;

	nb_timer_top_value( tops[index]);

	index = (index + 1)% 6;
}
